package com.example.shizi;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;

import com.airbnb.lottie.LottieAnimationView;
import com.example.shizi.databinding.FragmentLeanBinding;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link Lean_Fragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class Lean_Fragment extends Fragment {
    SoundPool sp; // 声明SoundPool的引用
    HashMap<Integer, Integer> hm; // 声明一个HashMap来存放声音文件
    int currStreamId;// 当前正播放的streamId


    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public Lean_Fragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment Lean_Fragment.
     */
    // TODO: Rename and change types and number of parameters
    public static Lean_Fragment newInstance(String param1, String param2) {
        Lean_Fragment fragment = new Lean_Fragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    /**
     * 从Assets/image中读取图片
     *
     * @param fileName 文件名
     */
    public static Bitmap getImageFromAssetsFile(Context context, String fileName) {
        Bitmap image = null;
        AssetManager am = context.getResources().getAssets();
        try {
            InputStream is = am.open("drawable/" + fileName + ".png");
            image = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }

    /**
     * 得到json文件中的内容
     *
     * @param context
     * @param fileName
     * @return
     */
    public static ArrayList<Character> getJsonArray(Context context, String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        //获得assets资源管理器
        AssetManager assetManager = context.getAssets();
        //使用IO流读取json文件内容
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
                    assetManager.open(fileName), StandardCharsets.UTF_8));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //读取JSON文件中的集合，并返回
        JSONObject jsonObject;
        JSONArray jsonArray;
        ArrayList nameList = new ArrayList<>();
        try {
            jsonObject = new JSONObject(stringBuilder.toString());
            jsonArray = jsonObject.getJSONArray("pictureList");
            for (int i = 0; i < jsonArray.length(); i++) {
                try {
                    nameList.add(jsonArray.get(i));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return nameList;
    }

    /**
     * 获得随机数
     * <p>
     * 得到答案的随机位置
     * 得到其余随机文字的位置
     */
    public static ArrayList<Integer> getRandomNum(int exNum) {
        ArrayList<Integer> array = new ArrayList<Integer>();
        Random random = new Random();
        for (int i = 0; array.size() < 4; i++) {
            int x = random.nextInt(177);
            if (!array.contains(x) && x != exNum) {
                array.add(x);
            }
        }
        int y = random.nextInt(4);
        array.set(y, exNum);
        return array;
    }

    /**
     * 初始化声音池
     */
    public void initSoundPool() {
        sp = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); // 创建SoundPool对象
        hm = new HashMap<Integer, Integer>(); // 创建HashMap对象
        hm.put(1, sp.load(getContext(), R.raw.rat_hit, 1)); // 加载声音文件musictest并且设置为1号声音放入hm中
        hm.put(2, sp.load(getContext(), R.raw.mushroom_hit, 2));
    }

    /**
     * 播放声音
     */
    public void playSound(int sound, int loop) { // 获取AudioManager引用
        AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
        // 获取当前音量
        float streamVolumeCurrent = am
                .getStreamVolume(AudioManager.STREAM_MUSIC);
        // 获取系统最大音量
        float streamVolumeMax = am
                .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        // 计算得到播放音量
        float volume = streamVolumeCurrent / streamVolumeMax;
        // 调用SoundPool的play方法来播放声音文件
        currStreamId = sp.play(hm.get(sound), volume, volume, 1, loop, 1.0f);
    }

    /**
     * 初始化lottie动画
     */
    private void initLottie(LottieAnimationView lott) {
        lott.setRepeatCount(0);
        lott.setSpeed(1.5f);
        lott.setVisibility(View.VISIBLE);
        lott.bringToFront();
        lott.addAnimatorListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                lott.setVisibility(View.INVISIBLE);
            }
        });
    }

    /**
     * 播放lottie动画
     */
    private void playLottie(View tmp, LottieAnimationView lott) {
        lott.setX((float) (tmp.getLeft() - 55.0));
//        lott.setY(tmp.getY());
        lott.setVisibility(View.VISIBLE);
        lott.playAnimation();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        MyViewModel myViewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class);
        FragmentLeanBinding binding;

        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_lean_, container, false);
        binding.setData(myViewModel);
        binding.setLifecycleOwner(getActivity());

        binding.close.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_lean_Fragment_to_home_Fragment));

        ArrayList pictureNameList = getJsonArray(getContext(), "pictureList.json");
        binding.image.setImageBitmap(getImageFromAssetsFile(getContext(), pictureNameList.get(myViewModel.getNumber().getValue()).toString()));
        binding.last.setVisibility(View.INVISIBLE);
        binding.next.setVisibility(View.INVISIBLE);

        //声音、动画初始化
        initLottie(binding.lottie);
        initSoundPool();

        ArrayList<Integer> randomNum = getRandomNum(myViewModel.getNumber().getValue());
        binding.answer1.setText((String) pictureNameList.get(randomNum.get(0)));
        binding.answer2.setText((String) pictureNameList.get(randomNum.get(1)));
        binding.answer3.setText((String) pictureNameList.get(randomNum.get(2)));
        binding.answer4.setText((String) pictureNameList.get(randomNum.get(3)));

        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                TextView textView = (TextView) view;
                if (textView.getText().toString().equals(pictureNameList.get(myViewModel.getNumber().getValue()).toString())) {
                    view.setClickable(false);
                    if (myViewModel.getFlag().getValue()) {
                        myViewModel.addRightNum();
                    }

                    binding.lottie.setImageAssetsFolder("success/images");
                    binding.lottie.setAnimation("success/data.json");

                    playLottie(view, binding.lottie);
                    playSound(1, 0);

                    binding.lottie.addAnimatorListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animator) {
                        }

                        @Override
                        public void onAnimationEnd(Animator animator) {
                            if (myViewModel.getNumber().getValue() == 176) {
                                NavController navController = Navigation.findNavController(view);
                                navController.navigate(R.id.action_lean_Fragment_to_endFragment);
                            } else if (myViewModel.getRightNum().getValue() + myViewModel.getWrongNum().getValue() == 6) {
                                myViewModel.add();
                                //非结尾情况，判断并跳转
                                if (myViewModel.getRightNum().getValue() > myViewModel.getWrongNum().getValue()) {
                                    NavController navController = Navigation.findNavController(view);
                                    navController.navigate(R.id.action_lean_Fragment_to_winFragment);
                                    myViewModel.getFlag().setValue(true);
                                } else {
                                    NavController navController = Navigation.findNavController(view);
                                    navController.navigate(R.id.action_lean_Fragment_to_loseFragment);
                                    myViewModel.getFlag().setValue(true);
                                }
                            } else {
                                textView.setClickable(true);
                                myViewModel.add();
                                ArrayList<Integer> randomNum = new ArrayList();
                                randomNum = getRandomNum(myViewModel.getNumber().getValue());
                                System.out.println(randomNum);
                                binding.answer1.setText((String) pictureNameList.get(randomNum.get(0)));
                                binding.answer2.setText((String) pictureNameList.get(randomNum.get(1)));
                                binding.answer3.setText((String) pictureNameList.get(randomNum.get(2)));
                                binding.answer4.setText((String) pictureNameList.get(randomNum.get(3)));
                                binding.image.setImageBitmap(getImageFromAssetsFile(getContext(), pictureNameList.get(myViewModel.getNumber().getValue()).toString()));
                            }
                            myViewModel.getFlag().setValue(true);
                            animator.removeAllListeners();
                        }

                        @Override
                        public void onAnimationCancel(Animator animator) {
                        }

                        @Override
                        public void onAnimationRepeat(Animator animator) {
                        }
                    });

                } else {
                    binding.lottie.setImageAssetsFolder("error/images");
                    binding.lottie.setAnimation("error/data.json");
                    binding.lottie.playAnimation();
                    playLottie(view, binding.lottie);
                    playSound(2, 0);
                    binding.lottie.postDelayed(null, 1200);
                    if (myViewModel.getFlag().getValue()) {
                        myViewModel.addWrongNum();
                        myViewModel.getFlag().setValue(false);
                    }
                }
            }
        };

        binding.answer1.setOnClickListener(listener);
        binding.answer2.setOnClickListener(listener);
        binding.answer3.setOnClickListener(listener);
        binding.answer4.setOnClickListener(listener);

        return binding.getRoot();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }

    }
}